#ifndef CAMERAFLYCAPTURE_H
#define CAMERAFLYCAPTURE_H
#include "AbstractCamera.hpp"
#include "FlyCapture2.h"
#include <iostream>
#include <sstream>
#include <queue>
#include <direct.h>
#include <opencv2/core/core.hpp>  
#include <opencv2/highgui/highgui.hpp>  
#include "opencv2/opencv.hpp"
#include <mutex>
#define SHOWINFO
#define SOFTWARE_TRIGGER_CAMERA
using namespace FlyCapture2;
using namespace std;

class CameraFlyCapture : public AbstractCamera
{
private:
	FlyCapture2::Error error;
	string _path;
	unsigned int RGBCameraSerial = 20137880;
	unsigned int SPECameraSerial = 16138111;
	PGRGuid guidRGB;
	PGRGuid guidSPE;
	Camera RGBcam;
	Camera SPEcam;
	BusManager busMgr;
	unsigned int numCameras = 0;

	void PrintBuildInfo();

	void PrintCameraInfo(CameraInfo *pCamInfo);

	void PrintError(FlyCapture2::Error error);

	int ConfigureTrigger(double timeDelay);

	


public:
	CameraFlyCapture() {};
	virtual int cameraInit();

	virtual void setWorkPath(const char * path);

	virtual double setRGBCameraGain(double time);

	virtual double setRGBCameraExposure(double time);

	virtual double setSPECameraGain(double time);

	virtual double setSPECameraExposure(double time);

	virtual bool camerasReady();


	virtual int runSingleAcq();

	virtual int runTriggerAcq(double time_delay = 0) override;

	virtual void stopAcq(int mode = 1);

	virtual void saveResualtWithPng();

	virtual void saveResualtWithJpeg();

	bool rgbCameraConnect();

	bool speCameraConnect();

	bool rgbCameraReady();

	bool speCameraReady();

	virtual ~CameraFlyCapture() {
		//error = RGBcam.Disconnect();
		//if (error != PGRERROR_OK)
		//{
		//	PrintError(error);
		//}

		//error = SPEcam.Disconnect();
		//if (error != PGRERROR_OK)
		//{
		//	PrintError(error);
		//}
	};

	//int restore() {
	//	using namespace cv;
	//	if (original_spe_image_queue.size() != 320)
	//		cout << "restroe error!" << endl;
	//	string filename = "D:\\Y_N_501.dat";
	//	FILE * Y = fopen(filename.c_str(),"r");
	//	if (Y == nullptr) {
	//		cout << "READ Y error!" << endl;
	//		return -1;
	//	}
	//	float *map = new float[912 * 1140 * 501];
	//	fread(map, sizeof(float), 912 * 1140 * 501, Y);

	//	vector<Image *> v;
	//	for (int i = 0; i < 320; i++) {
	//		v.push_back(original_spe_image_queue.front());
	//		original_spe_image_queue.pop();
	//	}
	//	for (int k = 0; k < 501; k++) {
	//		Mat out = Mat::zeros(1120, 880, CV_8UC1);
	//		for (int i = 0; i < 1120; i++) {
	//			for (int j = 0; j < 880; j++) {
	//				int img_idx = i % 80 * 4 + j % 4;
	//				int offset = i * 912 + j;
	//				int idx = (int)(map[offset * 501 + k] - 2050);
	//				uchar * tmp = v[img_idx]->GetData();
	//				out.at<uchar>(i, j) = tmp[idx];
	//			}
	//		}
	//		string outname = "D:\\mmm&lh\\project\\deviceMenager\\deviceMenager\\R3\\" + to_string(k) + ".png";
	//		imwrite(outname,out);
	//	}
	//}

	/*int mean() {
		if (original_spe_image_queue.size() != 160)
			cout << "restroe error!" << endl;
		vector<Image *> v;
		for (int i = 0; i < 160; i++) {
			v.push_back(original_spe_image_queue.front());
			original_spe_image_queue.pop();
		}
		for (int k = 0; k < 32; k++) {
			Mat out = Mat::zeros(2048, 2048, CV_8UC1);
			for (int i = 0; i < 2048; i++) {
				for (int j = 0; j < 2048; j++) {
					int point_value = 0;
					for (int s = 0; s < 5; s++) {
						int img_idx = s * 32 + k;
						int offset = i * 2048 + j;
						uchar * tmp = v[img_idx]->GetData();
						point_value += tmp[offset];
					}
					out.at<uchar>(i, j) = (uchar)(point_value / 5);
				}
			}
			string outname = _path + "/" + to_string(k) + ".png";
			imwrite(outname, out);
		}
		return 0;
	}*/
};
#endif